import Wfs from "./wfs";
import React from "react";
import { Collapse } from "antd";
import type { API } from "@/types/api";
import type { UploadProps } from "antd";
import { RcFile } from "antd/es/upload";
import { useNavigate } from "@umijs/max";
import type { CollapseProps } from "antd";
import { useState, useRef, useEffect } from "react";
import {
    Space,
    message,
    Upload,
    Radio,
    Drawer,
    Input,
    Button,
    Tooltip,
} from "antd";
import Editor, { loader } from "@monaco-editor/react";
import { QuestionCircleOutlined } from "@ant-design/icons";
import {
    DrawerForm,
    ProForm,
    ProFormSelect,
    ProFormText,
} from "@ant-design/pro-components";
import {
    postAllStypes,
    postReceiveFile,
    postRegisterApp,
} from "@/services/hosting/api";
import { postNgxTemp } from "@/services/hosting/api";
import { postAllNodesList } from "@/services/nodes/api";

loader.config({ paths: { vs: "/monaco-editor/vs" } });

interface Props {
    ifShow: boolean;
    setIfShow: (value: boolean) => void;
    refreshAllApps: () => void;
}

export const Register: React.FC<Props> = ({
    ifShow,
    setIfShow,
    refreshAllApps,
}) => {
    const { TextArea } = Input;
    const navigate = useNavigate();
    const [form] = ProForm.useForm();
    const [savePath, setSavePath] = useState("");
    const [timeDir, setTimeDir] = useState("");
    const [savePathError, setSavePathError] = useState(false);
    const [stypeValue, setStypeValue] = useState<string>("");
    const [nginxConfError, setNginxConfError] = useState("");
    const [nodeId, setNodeId] = useState<string>("0");
    const fontSize = 14;
    const [code, setCode] = useState("");
    const [uploadedFileInfo, setUploadedFileInfo] = useState<{
        name: string;
    } | null>(null);
    const [nodes, setNodes] = useState<{ label: string; value: string }[]>([]);

    const handleChoosePath = (path: string) => {
        // 设置选中的文件路径
        setSavePath(path);
        // 清除之前可能存在的错误状态
        setSavePathError(false);
        
        // 更新表单字段值
        form.setFieldsValue({
            file: path,
        });
        
        return path;
    };

    const ngxTemp = async () => {
        const res = await postNgxTemp(nodeId, navigate);
        if (res.status === "success") {
            setCode(res.message);
            form.setFieldsValue({
                nginx_conf: res.message,
            });
        }
    };
    const translateStype = (stype: string): string => {
        const lowerStype = stype.toLowerCase();
        switch (lowerStype) {
            case "java" || "Java":
                return "Java服务";
            case "static" || "Static":
                return "前端静态文件";
            default:
                return stype;
        }
    };
    const props: UploadProps = {
        name: "file",
        action: "/api/apps/hosting/receive_file",
        headers: {
            authorization: "authorization-text",
        },
        maxCount: 1,
        beforeUpload: (file: RcFile) => {
            const isJarOrWar =
                file.type === "application/java-archive" ||
                file.name.endsWith(".jar") ||
                file.name.endsWith(".war") ||
                file.name.endsWith(".zip");
            if (!isJarOrWar) {
                message.error("只能上传JAR、WAR、ZIP文件!");
                return false;
            }
            return true;
        },
        onChange(info) {
            const { status } = info.file;
            if (status === "uploading") {
                setSavePathError(false);
            }
            if (status === "done") {
                message.success(`${info.file.name} 上传成功`);
                setUploadedFileInfo({ name: info.file.name });
                form.setFieldsValue({
                    file: info.file.response?.message?.path || info.file.name,
                    time_dir: info.file.response?.message?.time_dir || "",
                });
            } else if (status === "error") {
                message.error(`${info.file.name} 上传失败`);
            }
        },
        onRemove(file) {
            form.setFieldsValue({
                file: undefined,
                time_dir: undefined,
            });
            setSavePath("");
            setUploadedFileInfo(null);
            return true;
        },
        customRequest: async ({ file, onSuccess, onError }) => {
            const formData = new FormData();
            formData.append("file", file as RcFile);
            return await postReceiveFile(formData, nodeId, navigate)
                .then((res) => {
                    if (typeof onSuccess === "function") {
                        onSuccess("ok", file as RcFile);
                    }
                    setSavePath(
                        typeof res.message === "object" && res.message.path
                            ? res.message.path
                            : "",
                    );
                    setTimeDir(
                        typeof res.message === "object" && res.message.time_dir
                            ? res.message.time_dir
                            : "",
                    );
                    setSavePathError(false);
                })
                .catch((error) => {
                    if (typeof onError === "function") {
                        onError(error as Error);
                    }
                });
        },
    };

    const [chooseFileFromServer, setChooseFileFromServer] = useState(false);
    let uploadRef = useRef<any>(null);
    const [position, setPosition] = useState<"local" | "fromServer">("local");
    const [stypes, setStypes] = useState<{ name: string; status: string }[]>(
        [],
    );

    const clearFieldError = (fieldName: string) => {
        form.setFields([
            {
                name: fieldName,
                errors: [],
            },
        ]);
    };

    const handleFieldChange = (fieldName: string, value: any) => {
        if (value && value !== "") {
            clearFieldError(fieldName);
        }
    };

    const uploadFromServer = (e: React.MouseEvent) => {
        setChooseFileFromServer(!chooseFileFromServer);
        message.info("正在从服务器选择文件...");
        return null;
    };
    const handleEditorChange = (value: string | undefined) => {
        if (value !== undefined) {
            // 同步到表单的nginx_conf字段
            form.setFieldsValue({ nginx_conf: value });
            // 清除之前的错误信息
            if (value.trim() !== "") {
                setNginxConfError("");
            }
        }
    };
    const NgxEditorTop: React.FC = () => {
        return (
            <Space>
                Nginx配置
                <Tooltip title="Nginx配置文件内容">
                    <QuestionCircleOutlined
                        style={{ color: "rgba(0, 0, 0, 0.45)" }}
                    />
                </Tooltip>
                {/* <Button
                    size={"small"}
                    onClick={async () => {
                        await ngxTemp();
                        setCode(form.getFieldValue("nginx_conf")); // 确保code状态更新
                    }}
                >
                    加载模板
                </Button> */}
            </Space>
        );
    };

    const items: CollapseProps["items"] = [
        {
            key: "1",
            label: "基础信息",
            collapsible: "disabled",
            children: (
                <>
                    <ProForm.Group>
                        <ProFormText
                            width="md"
                            name="alias"
                            label="应用名称"
                            placeholder="请输入名称"
                            rules={[
                                { required: true, message: "请输入应用名称" },
                            ]}
                            fieldProps={{
                                onChange: (e) => {
                                    handleFieldChange("alias", e.target.value);
                                    form.setFieldsValue({
                                        alias: e.target.value,
                                    });
                                },
                            }}
                        />
                        <ProFormSelect
                            options={stypes.map((stype) => ({
                                label: translateStype(stype.name),
                                value: stype.name,
                                disabled: stype.status === "disable",
                            }))}
                            width="md"
                            name="stype"
                            label={<span>应用类型</span>}
                            tooltip="托管应用的类型"
                            rules={[
                                { required: true, message: "请选择应用类型" },
                            ]}
                            fieldProps={{
                                onChange: (value) => {
                                    handleFieldChange("stype", value);
                                    setStypeValue(value as string);
                                    if (value !== "Static") {
                                        form.setFieldsValue({
                                            proxyConfig: undefined,
                                        });
                                    } else if (value === "Static") {
                                        ngxTemp();
                                    }
                                },
                            }}
                        />
                        <ProFormText
                            width="md"
                            name="version"
                            label="版本号"
                            placeholder="请输入版本号"
                            fieldProps={{
                                onChange: (e) =>
                                    handleFieldChange(
                                        "version",
                                        e.target.value,
                                    ),
                            }}
                        />
                        <ProFormText
                            width="md"
                            name="notes"
                            label="备注"
                            placeholder="请输入备注"
                            tooltip="建议填写当前版本的描述"
                            fieldProps={{
                                onChange: (e) =>
                                    handleFieldChange("notes", e.target.value),
                            }}
                        />
                        <ProFormSelect
                            width="md"
                            name="node"
                            label={<span>节点</span>}
                            tooltip="请选择要将应用注册到的节点"
                            rules={[{ required: true, message: "请选择节点" }]}
                            options={nodes}
                            fieldProps={{
                                onChange: (value) => {
                                    setNodeId(value as string);
                                },
                            }}
                        />
                    </ProForm.Group>
                    <>
                        <Space direction={"vertical"} style={{ width: "100%" }}>
                            <ProForm.Group>
                                <ProForm.Item
                                    label="软件包"
                                    required
                                    style={{ width: "100%", marginBottom: 0 }}
                                    validateStatus={
                                        savePathError ? "error" : ""
                                    }
                                    help={savePathError ? "请上传文件" : null}
                                >
                                    <Radio.Group
                                        value={position}
                                        onChange={(e) =>
                                            setPosition(e.target.value)
                                        }
                                    >
                                        <Radio.Button
                                            value="local"
                                        >
                                            本地上传
                                        </Radio.Button>
                                        <Radio.Button
                                            value="formserver"
                                            onClick={uploadFromServer}
                                        >
                                            从服务器选择
                                        </Radio.Button>
                                    </Radio.Group>
                                    <div
                                        style={{ minHeight: "15px", minWidth: "76vh", marginTop: "10px" }}
                                    >
                                        {position === "local" && (
                                            <Upload.Dragger {...props} ref={uploadRef}>
                                                <p className="ant-upload-text">点击选择文件或拖拽文件到此处上传</p>
                                                <p className="ant-upload-hint">
                                                    支持文件类型：jar、zip
                                                </p>
                                            </Upload.Dragger>
                                        )}
                                    </div>
                                </ProForm.Item>
                            </ProForm.Group>
                            {/* 代码编辑器部分 - 只在应用类型为Static时显示 */}
                            {stypeValue === "Static" && (
                                <ProForm.Item
                                    label={<NgxEditorTop />}
                                    required
                                    style={{ marginBottom: 0 }}
                                    validateStatus={
                                        nginxConfError ? "error" : ""
                                    }
                                    help={nginxConfError}
                                >
                                    <div
                                        style={{
                                            border: "1px solid #d9d9d9",
                                            borderRadius: "6px",
                                            overflow: "hidden",
                                            position: "relative",
                                        }}
                                    >
                                        <Editor
                                            height={"35vh"}
                                            language="nginx"
                                            theme="light"
                                            onChange={handleEditorChange}
                                            value={code}
                                            options={{
                                                fontSize: fontSize,
                                                minimap: { enabled: false },
                                                scrollBeyondLastLine: false,
                                                lineNumbers: "on",
                                                folding: true,
                                                lineDecorationsWidth: 10,
                                                lineNumbersMinChars: 3,
                                                wordWrap: "on",
                                                automaticLayout: true,
                                            }}
                                        />
                                    </div>
                                    <ProFormText name="nginx_conf" hidden />
                                    {nginxConfError && (
                                        <TextArea
                                            placeholder={nginxConfError}
                                            autoSize={{
                                                minRows: 2,
                                                maxRows: 6,
                                            }}
                                        />
                                    )}
                                </ProForm.Item>
                            )}
                        </Space>
                    </>
                </>
            ),
        },
        // 只在应用类型为Java时显示其他信息
        stypeValue === "Java" && {
            key: "2",
            label: "其他信息",
            children: (
                <>
                    <ProFormText
                        width="xl"
                        name="inpara"
                        label="JVM参数"
                        placeholder="请输入内容"
                        tooltip="应用启动时的JVM传参"
                        fieldProps={{
                            onChange: (e) =>
                                handleFieldChange("inpara", e.target.value),
                        }}
                    />
                    {/* <ProFormText
                        width="md"
                        name="port"
                        label="监听端口"
                        placeholder="请输入端口号"
                        rules={[
                            { required: true, message: "请输入监听端口" },
                            { pattern: /^\d+$/, message: "端口号必须是数字" }
                        ]}
                        fieldProps={{
                            onChange: (e) =>
                                handleFieldChange("port", e.target.value),
                        }}
                    />
                    <ProFormText
                        width="md"
                        name="keepalive"
                        label="保活策略"
                        placeholder="请输入保活策略"
                        rules={[
                            { required: true, message: "请输入保活策略" },
                            { pattern: /^[01]$/, message: "保活策略必须是0或1" }
                        ]}P
                        fieldProps={{
                            onChange: (e) =>
                                handleFieldChange("keepalive", e.target.value),
                        }}
                    /> */}
                </>
            ),
        },
    ].filter(Boolean) as CollapseProps["items"];

    const initStype = async () => {
        await postAllStypes(navigate).then((res) => {
            if (res.status === "error") {
                if (res.status_code === "VERIFICATION_FAILDED") {
                    const fieldErrors = Object.entries(res.message).map(
                        ([fieldName, errorMsg]) => {
                            return {
                                name: fieldName,
                                errors: [errorMsg as string],
                            };
                        },
                    );
                    form.setFields(fieldErrors);
                }
                message.error("表单验证失败，请检查必填字段");
                setIfShow(false);
            } else if (res.status === "success") {
                setStypes(res.message as { name: string; status: string }[]);
                const enabledStypes = (
                    res.message as { name: string; status: string }[]
                ).filter((stype) => stype.status === "enable");
                if (enabledStypes.length === 1) {
                    form.setFieldsValue({
                        stype: enabledStypes[0].name,
                    });
                    setStypeValue(enabledStypes[0].name);
                }
            } else {
                message.error("未知错误！");
            }
        });
    };
    const initNodesList = async () => {
        await postAllNodesList(nodeId, navigate).then((res: any) => {
            if (res.status === "success") {
                const nodesList = res.message.map((item: any) => {
                    // 翻译localhost为本机
                    if (item.host === "localhost") {
                        return { label: "本机", value: item.node_id };
                    }
                    return { label: item.host, value: item.node_id };
                });
                setNodes(nodesList);
                const localhostNode = nodesList.find((node: { label: string; value: string }) => node.label === "本机");
                if (localhostNode) {
                    form.setFieldsValue({
                        node: localhostNode.value,
                    });
                    setNodeId(localhostNode.value);
                } else if (nodesList.length === 1) {
                    form.setFieldsValue({
                        node: nodesList[0].value,
                    });
                    setNodeId(nodesList[0].value);
                }
            } else {
                message.error(res.message);
            }
        });
    };

    useEffect(() => {
        initStype();
        initNodesList();
        ngxTemp();
    }, []);

    const submitForm = async (
        values: API.PostRegisterAppParam & {
            stype: string;
            nginx_conf?: string;
        },
    ): Promise<boolean> => {
        setSavePathError(false);
        setNginxConfError("");

        if (!savePath) {
            setSavePathError(true);
            message.error("请上传文件");
            return false;
        }

        // 根据应用类型进行特定验证
        if (stypeValue === "Static") {
            const nginxConf = values.nginx_conf || "";
            if (!nginxConf || nginxConf.trim() === "") {
                setNginxConfError("Nginx配置不能为空");
                message.error("Nginx配置不能为空");
                return false;
            }
        }

        // 根据应用类型构建不同的请求对象
        let transformedValues: any;

        if (stypeValue === "Static") {
            // Static应用类型需要的字段
            transformedValues = {
                alias: values.alias,
                save_path: savePath,
                node: nodeId || "0",
                version: values.version || "",
                notes: values.notes || "",
                nginx_conf: values.nginx_conf || "",
                time_dir: timeDir,
            };
        } else if (stypeValue === "Java") {
            // Java应用类型需要的字段
            transformedValues = {
                alias: values.alias,
                save_path: savePath,
                node: nodeId || "0",
                time_dir: timeDir,
                inpara: values.inpara || "",
                port: values.port || "",
                keepalive: values.keepalive || "0",
                version: values.version || "",
                notes: values.notes || "",
            };
        } else {
            message.error("不支持的应用类型");
            return false;
        }

        return await postRegisterApp(
            transformedValues,
            stypeValue as "java" | "web",
            nodeId,
            navigator,
        )
            .then((res) => {
                if (res.status === "error") {
                    if (res.status_code === "VERIFICATION_FAILDED") {
                        const fieldErrors = Object.entries(res.message).map(
                            ([fieldName, errorMsg]) => {
                                if (fieldName === "save_path") {
                                    setSavePathError(true);
                                }
                                return {
                                    name: fieldName,
                                    errors: [errorMsg as string],
                                };
                            },
                        );
                        form.setFields(fieldErrors);
                    }
                    message.error(res.message as string);
                    if (
                        typeof res.message === "object" &&
                        res.message &&
                        "nginx_conf" in res.message &&
                        res.message.nginx_conf !== undefined &&
                        res.message.nginx_conf !== null &&
                        res.message.nginx_conf.length > 0
                    ) {
                        setNginxConfError(res.message.nginx_conf as any);
                    }
                    return false;
                } else if (res.status === "success") {
                    message.info(res.message as string);
                    if (refreshAllApps) {
                        refreshAllApps();
                    }
                    return true;
                }
                message.error("未知错误！");
                return false;
            })
            .catch((err) => {
                message.error(err.message);
                return false;
            });
    };

    return (
        <>
            <DrawerForm
                form={form}
                onOpenChange={setIfShow}
                title={<span>注册新应用</span>}
                open={ifShow}
                onFinish={async (e) => {
                    return submitForm(
                        e as API.PostRegisterAppParam & {
                            stype: string;
                            nginx_conf?: string;
                        },
                    );
                }}
                drawerProps={{
                    width: 800,
                    styles: {
                        body: {
                            overflowY: "auto",
                        },
                    },
                }}
            >
                <Collapse
                    items={items}
                    defaultActiveKey={["1", "2"]}
                ></Collapse>
            </DrawerForm>
            {chooseFileFromServer && (
                <Drawer
                    title="从服务器选择文件"
                    open={chooseFileFromServer}
                    width={"30%"}
                    onClose={() => setChooseFileFromServer(false)}
                >
                    <Wfs
                        ifshow={chooseFileFromServer}
                        changeShow={setChooseFileFromServer}
                        choosePath={handleChoosePath}
                    />
                </Drawer>
            )}
        </>
    );
};
